#include "HttpRequest.h"
#include <stdio.h>

static const HttpMethodName s_HttpMethodName[] = {
	HT_MAKE_METHOD(METHOD_NONE, ""),
	HT_MAKE_METHOD(METHOD_OPTIONS, "OPTIONS"),
	HT_MAKE_METHOD(METHOD_GET, "GET" ),                
	HT_MAKE_METHOD(METHOD_HEAD, "HEAD"),
	HT_MAKE_METHOD(METHOD_POST, "POST"),
	HT_MAKE_METHOD(METHOD_PUT, "PUT"),
	HT_MAKE_METHOD(METHOD_DELETE, "DELETE"), 
	HT_MAKE_METHOD(METHOD_TRACE, "TRACE"), 
	HT_MAKE_METHOD(METHOD_TRACK, "TRACK"),
	HT_MAKE_METHOD(METHOD_CONNECT, "CONNECT"),
	/*WebDAV Methods*/
	HT_MAKE_METHOD(METHOD_COPY, "COPY"),
	HT_MAKE_METHOD(METHOD_LOCK, "LOCK"),
	HT_MAKE_METHOD(METHOD_MKCOL, "MKCOL"),
	HT_MAKE_METHOD(METHOD_MOVE, "MOVE"),
	HT_MAKE_METHOD(METHOD_PROPFIND, "PROPFIND"),
	HT_MAKE_METHOD(METHOD_PROPPATCH, "PROPPATCH"),
	HT_MAKE_METHOD(METHOD_UNLOCK, "UNLOCK"),
	/*Others,for custom defined*/
};

static const ReqFieldName s_ReqFieldName[] = {
	HT_MAKE_REQ(REQ_NONE, ""),
	HT_MAKE_REQ(REQ_ACCEPT_CHAR, "Accept-Charset: "),
	HT_MAKE_REQ(REQ_ACCEPT_ENC, "Accept-Encoding: "),
	HT_MAKE_REQ(REQ_ACCEPT_LAN, "Accept-Language: "),
	HT_MAKE_REQ(REQ_ACCEPT_TYPE, "Accept: "),
	HT_MAKE_REQ(REQ_AUTH, "Authorization: "),
	HT_MAKE_REQ(REQ_CACHE_CONTROL, "Cache-Control: "),
	HT_MAKE_REQ(REQ_CONNECTION, "Connection: "),
	HT_MAKE_REQ(REQ_CONTENT_ENCODING, "Content-Encoding: "),
	HT_MAKE_REQ(REQ_CONTENT_LANGUAGE, "Content-Language: "),
	HT_MAKE_REQ(REQ_CONTENT_LENGTH, "Content-Length: "),
	HT_MAKE_REQ(REQ_CONTENT_MD5, "Content-MD5: "),
	HT_MAKE_REQ(REQ_CONTENT_TYPE, "Content-Type: "), 
	HT_MAKE_REQ(REQ_COOKIE, "Cookie: "),
	HT_MAKE_REQ(REQ_DAV, "DAV: "),
	HT_MAKE_REQ(REQ_DEPTH, "Depth: "),
	HT_MAKE_REQ(REQ_DESTINATION, "Destination: "),
	HT_MAKE_REQ(REQ_EXPECT, "Expect: "),
	HT_MAKE_REQ(REQ_FROM, "From: "),
	HT_MAKE_REQ(REQ_HOST, "Host: "),
	HT_MAKE_REQ(REQ_IF, "If: "),
	HT_MAKE_REQ(REQ_IF_MATCH, "If-Match: "),
	HT_MAKE_REQ(REQ_IF_MOD_SINCE, "If-Modified-Since: " ),
	HT_MAKE_REQ(REQ_IF_NONMATCH, "If-None-Match: "),
	HT_MAKE_REQ(REQ_IF_RANGE, "If-Range: "),
	HT_MAKE_REQ(REQ_IF_UNMOD_SINCE, "If-Unmodified-Since: "),
	HT_MAKE_REQ(REQ_LOCK_TOKEN, "Lock-Token: "),
	HT_MAKE_REQ(REQ_MAX_FORWARDS, "Max-Forwards: "),
	HT_MAKE_REQ(REQ_OVERWRITE, "Overwrite: "),
	HT_MAKE_REQ(REQ_PRAGMA, "Pragma: "),
	HT_MAKE_REQ(REQ_PROXY_AUTH, "Proxy-Authorization: "),
	HT_MAKE_REQ(REQ_RANGE, "Range: "),
	HT_MAKE_REQ(REQ_REFERER, "Referer: "),
	HT_MAKE_REQ(REQ_TE, "TE: "),
	HT_MAKE_REQ(REQ_TIMEOUT, "Timeout: "),
	HT_MAKE_REQ(REQ_TRANSFER_ENCODING, "Transfer-Encoding: "),
	HT_MAKE_REQ(REQ_USER_AGENT, "User-Agent: "),
	HT_MAKE_REQ(REQ_VIA, "Via: ")
	/*REQ_USER_DEFINED*/
};

HttpRequest::HttpRequest()
 : m_reqmtd(),m_fv(),m_host(),m_uri()
{
	m_fv.push_back(ReqFieldValue(REQ_ACCEPT_TYPE, DEFAULT_ACCEPT_TYPE));
	m_fv.push_back(ReqFieldValue(REQ_ACCEPT_LAN,  DEFAULT_ACCEPT_LAN));
	m_fv.push_back(ReqFieldValue(REQ_USER_AGENT,  DEFAULT_USER_AGENT));
	m_fv.push_back(ReqFieldValue(REQ_ACCEPT_ENC, DEFAULT_ACCEPT_ENC));
	m_fv.push_back(ReqFieldValue(REQ_HOST, m_host));
}

HttpRequest::~HttpRequest()
{
}

HttpRequest::HttpRequest(const string& host, const string& uri, HttpReqMethod mtd)
: m_host(host), m_uri(uri), m_reqmtd(mtd, s_HttpMethodName[mtd].mstr)
{
	m_fv.push_back(ReqFieldValue(REQ_ACCEPT_TYPE, DEFAULT_ACCEPT_TYPE));
	m_fv.push_back(ReqFieldValue(REQ_ACCEPT_LAN,  DEFAULT_ACCEPT_LAN));
	m_fv.push_back(ReqFieldValue(REQ_USER_AGENT,  DEFAULT_USER_AGENT));
	m_fv.push_back(ReqFieldValue(REQ_ACCEPT_ENC, DEFAULT_ACCEPT_ENC));
	m_fv.push_back(ReqFieldValue(REQ_HOST, m_host));
}

HttpRequest::HttpRequest(const HttpRequest& req)
 : m_reqmtd(req.m_reqmtd),
   m_fv(req.m_fv),
   m_host(req.m_host),
   m_uri(req.m_uri)
{
}

HttpRequest& HttpRequest::operator= (const HttpRequest& req)
{
	if(this != &req) {
		m_reqmtd = req.m_reqmtd;
		m_fv.assign(req.m_fv.begin(), req.m_fv.end());
		m_host = req.m_host;
		m_uri = req.m_uri;
	}
	return *this;
}


string HttpRequest::ToString() const
{
	string s = "";
	s.reserve(512);
	s += m_reqmtd.mstr;
	s += " ";
	s += m_uri;
	s += " HTTP/1.1\r\n";

	for(field_const_iterator it=m_fv.begin(); it!=m_fv.end(); ++it) {
		s += s_ReqFieldName[it->field].name;
		s += it->value;
		s += "\r\n";
	}
	s += "\r\n";

	return s;
}

void HttpRequest::SetMethod(HttpReqMethod method)
{
	m_reqmtd.method = method;
	m_reqmtd.mstr = s_HttpMethodName[method].mstr;
}

void HttpRequest::SetHost(const string& host)
{
	m_host = host;
	SetField(REQ_HOST, host);
}

void HttpRequest::SetUri(const string& uri)
{
	m_uri = uri;
}

int  HttpRequest::SetField(HttpReqField field, const string& value)
{
	int retval = 0;
	for(field_iterator it=m_fv.begin(); it!=m_fv.end(); ++it) {
		if(it->field == field) {
			it->value = value;
			retval = 1;
			break;
		}
	}
	if(!retval) {
		m_fv.push_back(ReqFieldValue(field, value));
		retval = 2;
	}
	return retval;
}

void HttpRequest::SetUserAgent(const string& ua)
{
	SetField(REQ_USER_AGENT, ua);
}

void HttpRequest::SetAcceptType(const string& type)
{
	SetField(REQ_ACCEPT_TYPE, type);
}

void HttpRequest::SetAcceptEncoding(const string& encoding)
{
	SetField(REQ_ACCEPT_ENC, encoding);
}
void HttpRequest::SetConnection(const string& connection)
{
	SetField(REQ_CONNECTION, connection);
}

void HttpRequest::SetCookie(const string& cookie)
{
	SetField(REQ_COOKIE, cookie);
}

void HttpRequest::SetContentType(const string& type)
{
	SetField(REQ_CONTENT_TYPE, type);
}

void HttpRequest::SetContentLength(const string& length)
{
	SetField(REQ_CONTENT_LENGTH, length);
}

void HttpRequest::SetContentLength(int length)
{
	char buf[32];
	sprintf(buf, "%d", length);
	SetField(REQ_CONTENT_LENGTH, buf);
}

void HttpRequest::SetReferer(const string& referer)
{
	SetField(REQ_REFERER, referer);
}

void HttpRequest::SetRange(const string& range)
{
	SetField(REQ_RANGE, range);
}

void HttpRequest::SetAuthorization(const string& auth)
{
	SetField(REQ_AUTH, auth);
}

int HttpRequest::DelField(HttpReqField field)
{
	int retval = 0;
	for(field_iterator it=m_fv.begin(); it!=m_fv.end(); ++it) {
		if(it->field == field ) {
			m_fv.erase(it);
			retval = 1;
			break;
		}
	}
	return retval;
}


//EOF
